/*
 * Copyright (C) 2009-2018 Hangzhou Iroly Technology Co., Ltd. All rights reserved
 */
package com.ws.soa.consumer.system;



import com.ws.soa.consumer.common.enums.BizCodeEnum;
import com.ws.soa.consumer.util.ApiResultUtil;
import com.ws.soa.consumer.util.LogUtil;

import org.slf4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;

import ch.qos.logback.classic.Level;

/**
 * Date: 2019-02-13 Time: 18:32 Description: 全局异常处理类
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

  private Logger loggerExceptionHandler = LogUtil.EXCEPTION_HANDLER;

  /**
   * 400 - Bad Request
   */
  @ResponseStatus(HttpStatus.OK)
  @ExceptionHandler(MissingServletRequestParameterException.class)
  public ResultMap handleMissingServletRequestParameterException(HttpServletRequest request,
                                                                 MissingServletRequestParameterException e) {
    LogUtil.log(loggerExceptionHandler, Level.ERROR,
                LogUtil.formatLog("MissingServletRequestParameterException",
                                  request.getRequestURL(), request.getParameterMap()), e);
    return ApiResultUtil
        .failResult(BizCodeEnum.MISSING_SERVLET_REQUEST_PARAMETER_EXCEPTION.getCode()
            , BizCodeEnum.MISSING_SERVLET_REQUEST_PARAMETER_EXCEPTION.getMessage());
  }

  /**
   * 400 - Bad Request
   */
  @ResponseStatus(HttpStatus.OK)
  @ExceptionHandler(HttpMessageNotReadableException.class)
  public ResultMap handleHttpMessageNotReadableException(HttpServletRequest request,
                                                         HttpMessageNotReadableException e) {
    LogUtil.log(loggerExceptionHandler, Level.ERROR,
                LogUtil.formatLog("HttpMessageNotReadableException",
                                  request.getRequestURL(), request.getParameterMap()), e);
    return ApiResultUtil.failResult(BizCodeEnum.HTTP_MESSAGE_NOT_READABLE_EXCEPTION.getCode()
        , BizCodeEnum.HTTP_MESSAGE_NOT_READABLE_EXCEPTION.getMessage());
  }

  /**
   * 400 - Bad Request
   */
  @ResponseStatus(HttpStatus.OK)
  @ExceptionHandler(MethodArgumentNotValidException.class)
  public ResultMap handleMethodArgumentNotValidException(HttpServletRequest request,
                                                         MethodArgumentNotValidException e) {
    LogUtil.log(loggerExceptionHandler, Level.ERROR,
                LogUtil.formatLog("MethodArgumentNotValidException",
                                  request.getRequestURL(), request.getParameterMap()), e);
    return ApiResultUtil.failResult(BizCodeEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getCode()
        , BizCodeEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getMessage());
  }

  /**
   * 400 - Bad Request
   */
  @ResponseStatus(HttpStatus.OK)
  @ExceptionHandler(BindException.class)
  public ResultMap handleBindException(HttpServletRequest request, BindException e) {
    LogUtil.log(loggerExceptionHandler, Level.ERROR, LogUtil.formatLog("BindException",
                                                                       request.getRequestURL(),
                                                                       request.getParameterMap()),
                e);
    return ApiResultUtil.failResult(BizCodeEnum.BIND_EXCEPTION.getCode()
        , BizCodeEnum.BIND_EXCEPTION.getMessage());
  }

  /**
   * 400 - Bad Request
   */
  @ResponseStatus(HttpStatus.OK)
  @ExceptionHandler(ConstraintViolationException.class)
  public ResultMap handleServiceException(HttpServletRequest request,
                                          ConstraintViolationException e) {
    LogUtil
        .log(loggerExceptionHandler, Level.ERROR, LogUtil.formatLog("ConstraintViolationException",
                                                                    request.getRequestURL(),
                                                                    request.getParameterMap()), e);
    return ApiResultUtil.failResult(BizCodeEnum.CONSTRAINT_VIOLATION_EXCEPTION.getCode()
        , BizCodeEnum.CONSTRAINT_VIOLATION_EXCEPTION.getMessage());
  }

  /**
   * 400 - Bad Request
   */
  @ResponseStatus(HttpStatus.OK)
  @ExceptionHandler(ValidationException.class)
  public ResultMap handleValidationException(HttpServletRequest request, ValidationException e) {
    LogUtil.log(loggerExceptionHandler, Level.ERROR, LogUtil.formatLog("ValidationException",
                                                                       request.getRequestURL(),
                                                                       request.getParameterMap()),
                e);
    return ApiResultUtil.failResult(BizCodeEnum.VALIDATION_EXCEPTION.getCode()
        , BizCodeEnum.VALIDATION_EXCEPTION.getMessage());
  }

  /**
   * 404 - Not Found
   */
  @ExceptionHandler(value = {NoHandlerFoundException.class})
  @ResponseStatus(HttpStatus.OK)
  public ResultMap handlerNoHandlerFoundException(HttpServletRequest request,
                                                  NoHandlerFoundException e) {
    LogUtil.log(loggerExceptionHandler, Level.ERROR, LogUtil.formatLog("NoHandlerFoundException",
                                                                       request.getRequestURL(),
                                                                       request.getParameterMap()));
    return ApiResultUtil.failResult(BizCodeEnum.NO_HANDLER_FOUND_EXCEPTION.getCode()
        , BizCodeEnum.NO_HANDLER_FOUND_EXCEPTION.getMessage());
  }

  /**
   * 405 - Method Not Allowed
   */
  @ResponseStatus(HttpStatus.OK)
  @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
  public ResultMap handleHttpRequestMethodNotSupportedException(HttpServletRequest request,
                                                                HttpRequestMethodNotSupportedException e) {
    LogUtil.log(loggerExceptionHandler, Level.ERROR,
                LogUtil.formatLog("HttpRequestMethodNotSupportedException",
                                  request.getRequestURL(), request.getParameterMap()), e);
    return ApiResultUtil
        .failResult(BizCodeEnum.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION.getCode()
            , BizCodeEnum.HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION.getMessage());
  }

  /**
   * 415 - Unsupported Media Type
   */
  @ResponseStatus(HttpStatus.OK)
  @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
  public ResultMap handleHttpMediaTypeNotSupportedException(HttpServletRequest request,
                                                            HttpMediaTypeNotSupportedException e) {
    LogUtil.log(loggerExceptionHandler, Level.ERROR,
                LogUtil.formatLog("HttpMediaTypeNotSupportedException",
                                  request.getRequestURL(), request.getParameterMap()), e);
    return ApiResultUtil.failResult(BizCodeEnum.HTTP_MEDIA_TYPE_NOT_SUPPORTED_EXCEPTION.getCode()
        , BizCodeEnum.HTTP_MEDIA_TYPE_NOT_SUPPORTED_EXCEPTION.getMessage());
  }



  /**
   * 500 - Internal Server Error
   */
  @ResponseStatus(HttpStatus.OK)
  @ExceptionHandler(Exception.class)
  public ResultMap handleException(HttpServletRequest request, Exception e) {
    LogUtil.log(loggerExceptionHandler, Level.ERROR, LogUtil.formatLog("Exception",
                                                                       request.getRequestURL(),
                                                                       request.getParameterMap()),
                e);
    return ApiResultUtil.failResult(BizCodeEnum.REQUEST_FAIL_EXCEPTION.getCode(),
                                    BizCodeEnum.REQUEST_FAIL_EXCEPTION.getMessage());
  }

}

